package com.tcm.ucenter.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.base.core.dozer.DozerConvert;
import com.base.core.exception.ServiceException;
import com.base.core.idworker.IdContext;
import com.base.core.lang.StringUtils;
import com.base.core.utils.JwtUtils;
import com.base.core.utils.R;
import com.base.genid.generator.UidGenerator;
import com.tcm.ucenter.domain.dto.UserDTO;
import com.tcm.ucenter.domain.entity.User;
import com.tcm.ucenter.domain.enums.BusinessCodeEnum;
import com.tcm.ucenter.mapper.UserMapper;
import com.tcm.user.constants.enums.ClientTypeEnum;
import com.tcm.user.constants.enums.LoginTypeEnum;
import com.tcm.user.model.entity.LoginAuth;
import com.tcm.user.model.query.LoginAuthQuery;
import com.tcm.user.service.UserService;
import io.jsonwebtoken.Claims;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.stream.Collectors;


@DubboService(version = "0.0.1-alpha", delay = -1, retries = 3)
public class UserDetailServiceImpl implements UserDetailService {

    @Autowired
    private UserMapper userMapper;

    @DubboReference(version = "0.0.1-beta", group = "cached-uid", check = false, retries = 3)
    private UidGenerator uidGenerator;

    @DubboReference(version = "1.0.0", check = false, lazy = true)
    private UserService userService;

    /**
     * 新增
     *
     * @param userParams
     * @return
     */
    @Override
    public R save(UserDTO userParams) throws ServiceException {
        if (ObjectUtil.isEmpty(userParams)) {
            return R.fail(BusinessCodeEnum.USER_PARAMS_NOT_FOUND);
        }
        if (ObjectUtil.isEmpty(userParams.getUserId())) {
            return R.fail(BusinessCodeEnum.USER_ID_NOT_FOUND);
        }
        try {
            User user = userMapper.findByUserId(userParams.getUserId());
            if (ObjectUtil.isEmpty(user)) {
                user = DozerConvert.copyProperties(userParams, User.class);
                user.setDeleted(new Byte("0"));
                user.setUpdateTime(DateUtil.date());
                user.setIsVerify(new Byte("0"));
                user.setCreateTime(DateUtil.date());
                user.setId(uidGenerator.getUID());
                userMapper.insert(user);
            } else {
                user = DozerConvert.copyProperties(userParams, User.class);
                user.setUpdateTime(DateUtil.date());
                userMapper.update(user);
            }
            LoginAuth loginAuth = new LoginAuth();
            loginAuth.setId(userParams.getUserId());
            loginAuth.setNickname(userParams.getNickname());
            loginAuth.setAvatar(userParams.getAvatar());
            userService.update(loginAuth);
        } catch (ServiceException e) {
            return R.fail(e.getResult().getCode(), e.getResult().getMsg());
        } catch (Exception e) {
            return R.fail(e.getMessage());
        }
        return R.success();
    }

    /**
     * 更新
     *
     * @param userParams
     * @return
     */
    @Override
    public void update(UserDTO userParams) throws ServiceException {

        try {
            if (ObjectUtil.isEmpty(userParams)) {
                R.throwFail(BusinessCodeEnum.USER_PARAMS_NOT_FOUND);
            }
            if (ObjectUtil.isEmpty(userParams.getUserId())) {
                R.throwFail(BusinessCodeEnum.USER_ID_NOT_FOUND);
            }

            //查询账号是否存在
            User users = this.userMapper.findByUserId(userParams.getUserId());
            if (ObjectUtil.isEmpty(users)) {
                R.throwFail(BusinessCodeEnum.FAILED_TO_QUERY_USER);
            }
            User user = DozerConvert.copyProperties(userParams, User.class);
            user.setDeleted(new Byte("0"));
            user.setUpdateTime(DateUtil.date());
            userMapper.update(user);

        } catch (ServiceException e) {
            R.throwOnFail(e.getResult());
        }
    }

    /**
     * 获取单条数数据
     *
     * @param userId
     * @return
     */
    @Override
    public UserDTO findUserByUserId(Long userId) {
        UserDTO userDto = null;
        try {
            User user = userMapper.findByUserId(userId);
            //获得头像昵称
            LoginAuthQuery loginAuthQuery = new LoginAuthQuery();
            loginAuthQuery.setId(userId);
            R ret = userService.queryUser(loginAuthQuery);
            if (ObjectUtil.isNotEmpty(user)) {
                userDto = DozerConvert.copyProperties(user, UserDTO.class);
                if(ret.isSuccess() && ret.getData() != null){
                    LoginAuth loginAuth = (LoginAuth) ret.getData();
                    userDto.setAvatar(loginAuth.getAvatar());
                    if(StringUtils.isNotBlank(loginAuth.getNickname())){
                        userDto.setNickname(loginAuth.getNickname());
                    }else {
                        //号码脱敏
                        String mobile = loginAuth.getMobile().replaceAll("(\\w{3})\\w*(\\w{4})", "$1****$2");
                        userDto.setNickname(mobile);
                    }
                    userDto.setMobile(loginAuth.getMobile());
                }
            }
        } catch (ServiceException e) {
            e.printStackTrace();
            R.throwFail(BusinessCodeEnum.FAILED_TO_QUERY_USER);
        }
        return userDto;
    }

    /**
     * 获得用户列表
     *
     * @param userIds
     * @return Doctor
     */
    @Override
    public List<UserDTO> listUserByUserIds(List<Long> userIds) throws ServiceException {
        List<User> users = userMapper.listUserByUserIds(userIds);
        if (users == null || users.isEmpty()) {
            return null;
        }
        List<UserDTO> userDTOS = users.stream().map(user -> {
            UserDTO userDTO = new UserDTO();
            BeanUtils.copyProperties(user, userDTO);
            return userDTO;
        }).collect(Collectors.toList());
        return userDTOS;
    }

    /**
     * 获取单条数数据
     *
     * @param token
     * @return
     */
    @Override
    public UserDTO findUserByToken(String token) throws ServiceException {
        UserDTO userDto = null;
        try {
            JwtUtils jwtUtils = new JwtUtils();
            Claims claims = jwtUtils.decode(token);
            if (ObjectUtil.isEmpty(claims)) {
                R.throwFail(BusinessCodeEnum.TOKEN_FAIL_PARSE);
            }
            Long userId = (Long) claims.get("userId");
            User user = userMapper.findByUserId(userId);
            if (ObjectUtil.isNotEmpty(user)) {
                userDto = DozerConvert.copyProperties(user, UserDTO.class);
            } else {
                userDto = new UserDTO();
                userDto.setUserId(userId);
            }
        } catch (ServiceException e) {
            e.printStackTrace();
            R.throwFail(BusinessCodeEnum.FAILED_TO_QUERY_USER);
        }
        return userDto;
    }

    @Override
    public void changeMobile(String mobile, Long userId) throws ServiceException {
        if (ObjectUtil.isEmpty(userId)) {
            R.throwFail(BusinessCodeEnum.USER_ID_NOT_FOUND);
        }
        if (StringUtils.isEmpty(mobile)) {
            R.throwFail(BusinessCodeEnum.SMS_IDENTIFIER_NOT_EMPTY);
        }
        try {
            User user = new User();
            user.setMobile(mobile);
            user.setUserId(userId);
            userMapper.update(user);
        } catch (ServiceException e) {
            R.throwFail(BusinessCodeEnum.UPDATE_FAIL);
        }
    }

    @Override
    public void updateAvatar(String avatar, Long userId) throws ServiceException {
        if (ObjectUtil.isEmpty(userId)) {
            R.throwFail(BusinessCodeEnum.USER_ID_NOT_FOUND);
        }
        if (StringUtils.isEmpty(avatar)) {
            R.throwFail(BusinessCodeEnum.AVATAR_PARAMS_NOT_FOUND);
        }
        try {
            User user = new User();
            user.setAvatar(avatar);
            user.setId(userId);
            userMapper.update(user);
        } catch (ServiceException e) {
            R.throwFail(BusinessCodeEnum.AVATAR_UPDATE_FAIL);
        }
    }


}
